<template>
  <div id="app">
    <!-- 输入原料信息的表单 -->
    <h2 class="form-title">输入原料信息</h2>
    <form @submit.prevent="addRawMaterial" class="form-container">
      <div v-for="(rawMaterial, rawIndex) in newRawMaterials" :key="rawIndex">
        <div class="input-group">
          <label class="form-label">
            原料名称:
            <input v-model="rawMaterial.name" type="text" />
          </label>
          <button
            @click.prevent="addNewRawMaterial(rawIndex)"
            class="add-button"
            v-if="rawIndex === newRawMaterials.length - 1"
          >
            +
          </button>
        </div>
        <div
          v-for="(component, compIndex) in rawMaterial.components"
          :key="compIndex"
        >
          <div class="component-input-group">
            <label class="form-label">
              成分名称:
              <input v-model="component.name" type="text" />
            </label>
            <label class="form-label">
              成分占比:
              <input v-model="component.percentage" type="number" step="0.01" />
            </label>
            <button
              @click.prevent="removeComponent(rawIndex, compIndex)"
              v-if="rawMaterial.components.length > 1"
              class="remove-button"
            >
              移除
            </button>
            <button
              @click.prevent="addComponent(rawIndex)"
              v-if="compIndex === rawMaterial.components.length - 1"
              class="add-button"
            >
              +
            </button>
          </div>
        </div>
        <label class="form-label">
          重量:
          <input v-model="rawMaterial.weight" type="number" />
        </label>
      </div>
      <button type="submit" class="submit-button">添加原料</button>
    </form>

    <!-- 显示原料表格 -->
    <h2 class="form-title">原料列表</h2>
    <ag-grid-vue
      class="ag-theme-balham table-container"
      style="width: 100%; height: 300px"
      :columnDefs="columnDefs"
      :rowData="rawMaterials"
      :modules="modules"
    ></ag-grid-vue>

    <!-- 输入所需合成坯料信息的表单 -->
    <h2 class="form-title">输入所需合成坯料信息</h2>
    <form @submit.prevent="calculateRawMaterialUsage" class="form-container">
      <label class="form-label">
        坯料名称:
        <input v-model="billetName" type="text" />
      </label>
      <div
        v-for="(targetComponent, index) in targetComponents"
        :key="index"
        class="target-component-input-group"
      >
        <label class="form-label">
          目标成分名称:
          <input v-model="targetComponent.name" type="text" />
        </label>
        <label class="form-label">
          目标成分占比:
          <input
            v-model="targetComponent.percentage"
            type="number"
            step="0.01"
          />
        </label>
        <button
          @click.prevent="addTargetComponent"
          v-if="index === targetComponents.length - 1"
          class="add-button"
        >
          +
        </button>
        <button
          @click.prevent="removeTargetComponent"
          v-if="
            targetComponents.length > 1 && index === targetComponents.length - 1
          "
          class="remove-button"
        >
          移除目标成分
        </button>
      </div>
      <label class="form-label">
        重量:
        <input v-model="targetWeight" type="number" />
      </label>
      <button type="submit" class="submit-button">计算原料用量</button>
    </form>

    <!-- 显示计算结果的表格 -->
    <h2 class="form-title">配成坯料所需各原料用量</h2>
    <ag-grid-vue
      class="ag-theme-balham table-container"
      style="width: 100%; height: 300px"
      :columnDefs="resultColumnDefs"
      :rowData="rawMaterialUsageResults"
      :modules="modules"
    ></ag-grid-vue>

    <!-- 合成和取消按钮 -->
    <div class="button-container">
      <button @click="synthesize" class="action-button">合成</button>
      <button @click="cancel" class="action-button">取消</button>
    </div>

    <!-- 显示合成记录 -->
    <h2 class="form-title">合成记录</h2>
    <div v-for="(record, index) in synthesisRecords" :key="index" class="record-container">
      <p>坯料名称: {{ record.billetName }}</p>
      <p>重量: {{ record.targetWeight }}</p>
      <p>使用的原料:</p>
      <ul>
        <li v-for="(usage, usageIndex) in record.rawMaterialUsageResults" :key="usageIndex">
          {{ usage.name }}: {{ usage.usage }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { AgGridVue } from "ag-grid-vue3";
import { ClientSideRowModelModule } from "ag-grid-community";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-balham.css";

// 定义表格列定义
const columnDefs = ref([
  { headerName: "原料名称", field: "name" },
  { headerName: "重量", field: "weight" },
]);

// 定义结果表格列定义
const resultColumnDefs = [
  { headerName: "原料名称", field: "name" },
  { headerName: "所需用量", field: "usage" },
];

// 存储原料信息
const rawMaterials = ref([]);
// 存储新原料信息
const newRawMaterials = ref([
  {
    name: "",
    components: [{ name: "", percentage: 0 }],
    weight: 0,
  },
]);
// 存储目标坯料的成分信息
const targetComponents = ref([{ name: "", percentage: 0 }]);
// 存储所需合成坯料的重量
const targetWeight = ref(0);
// 存储计算结果
const rawMaterialUsageResults = ref([]);
// 存储所需模块
const modules = [ClientSideRowModelModule];
// 存储坯料名称
const billetName = ref("");
// 存储合成记录
const synthesisRecords = ref([]);

// 添加新的原料输入项
const addNewRawMaterial = () => {
  newRawMaterials.value.push({
    name: "",
    components: [{ name: "", percentage: 0 }],
    weight: 0,
  });
};

// 添加成分输入框
const addComponent = (rawIndex) => {
  newRawMaterials.value[rawIndex].components.push({ name: "", percentage: 0 });
};

// 移除成分输入框
const removeComponent = (rawIndex, compIndex) => {
  newRawMaterials.value[rawIndex].components.splice(compIndex, 1);
};

// 添加目标成分输入框
const addTargetComponent = () => {
  targetComponents.value.push({ name: "", percentage: 0 });
};

// 移除目标成分输入框
const removeTargetComponent = () => {
  targetComponents.value.pop();
};

// 更新列定义
const updateColumnDefs = () => {
  const allComponents = new Set();
  rawMaterials.value.forEach((rawMaterial) => {
    rawMaterial.components.forEach((component) => {
      allComponents.add(component.name);
    });
  });
  const newColumnDefs = [
    { headerName: "原料名称", field: "name" },
    { headerName: "重量", field: "weight" },
  ];
  allComponents.forEach((componentName) => {
    newColumnDefs.push({
      headerName: componentName,
      field: `components.${componentName}`,
      valueGetter: (params) => {
        const component = params.data.components.find(
          (c) => c.name === componentName
        );
        return component? component.percentage : 0;
      },
    });
  });
  columnDefs.value = newColumnDefs;
};

// 添加原料到表格的方法
const addRawMaterial = () => {
  newRawMaterials.value.forEach((newRawMaterial) => {
    if (newRawMaterial.name && newRawMaterial.weight) {
      const validComponents = newRawMaterial.components.every(
        (component) =>
          component.name &&
          component.percentage >= 0 &&
          component.percentage <= 100
      );
      if (validComponents) {
        rawMaterials.value.push({ ...newRawMaterial });
      } else {
        alert("成分信息无效，请检查成分名称和占比");
      }
    } else {
      alert("原料名称和重量不能为空，且重量必须大于0");
    }
  });
  updateColumnDefs();
  newRawMaterials.value = [
    {
      name: "",
      components: [{ name: "", percentage: 0 }],
      weight: 0,
    },
  ];
};

// 计算原料用量的方法
const calculateRawMaterialUsage = () => {
  if (targetWeight.value > 0 && targetComponents.value.length > 0) {
    const validTargetComponents = targetComponents.value.every(
      (component) =>
        component.name &&
        component.percentage >= 0 &&
        component.percentage <= 100
    );
    if (validTargetComponents) {
      const results = {};
      targetComponents.value.forEach((targetComponent) => {
        const targetComponentName = targetComponent.name;
        const targetComponentPercentage = targetComponent.percentage;
        rawMaterials.value.forEach((rawMaterial) => {
          const rawComponent = rawMaterial.components.find(
            (c) => c.name === targetComponentName
          );
          if (rawComponent) {
            const usage =
              (targetWeight.value * targetComponentPercentage) /
              rawComponent.percentage;
            if (results[rawMaterial.name]) {
              results[rawMaterial.name] += usage;
            } else {
              results[rawMaterial.name] = usage;
            }
          }
        });
      });
      rawMaterialUsageResults.value = Object.entries(results).map(
        ([name, usage]) => ({ name, usage })
      );
    } else {
      alert("目标成分信息无效，请检查成分名称和占比");
    }
  } else {
    alert("目标重量必须大于0，且至少有一个目标成分");
  }
};

// 合成操作方法
const synthesize = () => {
  if (billetName.value) {
    const record = {
      billetName: billetName.value,
      targetWeight: targetWeight.value,
      rawMaterialUsageResults: rawMaterialUsageResults.value,
    };
    synthesisRecords.value.push(record);
  } else {
    alert("请输入坯料名称");
    return;
  }

  rawMaterialUsageResults.value.forEach((result) => {
    const rawMaterial = rawMaterials.value.find(
      (item) => item.name === result.name
    );
    if (rawMaterial) {
      rawMaterial.weight -= result.usage;
      if (rawMaterial.weight <= 0) {
        // 如果原料重量减为 0 或负数，从原料列表中移除
        const index = rawMaterials.value.indexOf(rawMaterial);
        rawMaterials.value.splice(index, 1);
      }
    }
  });
  // 清空计算结果
  rawMaterialUsageResults.value = [];
  targetComponents.value = [{ name: "", percentage: 0 }];
  targetWeight.value = 0;
  billetName.value = "";
  updateColumnDefs();
};

// 取消操作方法
const cancel = () => {
  // 清空计算结果
  rawMaterialUsageResults.value = [];
  targetComponents.value = [{ name: "", percentage: 0 }];
  targetWeight.value = 0;
  billetName.value = "";
};
</script>

<style scoped>
body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
  padding: 20px;
}

.form-title {
  margin-bottom: 10px;
  color: #333;
}

.form-container {
  background-color: #fff;
  padding: 20px;
  border-radius: 5px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.form-label {
  display: block;
  margin-bottom: 5px;
}

.input-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.component-input-group {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.add-button,
.submit-button {
  background-color: #007bff;
  color: white;
  padding: 5px 10px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.add-button:hover,
.submit-button:hover {
  background-color: #0056b3;
}

.remove-button {
  background-color: #dc3545;
  color: white;
  padding: 5px 10px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.remove-button:hover {
  background-color: #c82333;
}

.table-container {
  margin-bottom: 20px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}

.button-container {
  text-align: center;
  margin-top: 20px;
}

.action-button {
  background-color: #28a745;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;
  margin: 0 10px;
}

.action-button:hover {
  background-color: #218838;
}

.target-component-input-group {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.record-container {
  background-color: #fff;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
  margin-bottom: 10px;
}
</style>